﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Dominion.Core;


namespace Dominion.Core.Factories
{

    public enum GameType
    {
        FirstGame,
        BigMoney,
        Interaction,
    }

    public static class BoardFactory
    {


        private const int KingdomsToShuffle = 10;
        private const int KingdomsCardPerKind = 12;

        public static List<Card> Shuffle
        {
            get
            {
                List<Card> cards = InitBoardBase();
                cards.AddRange(CreateKingdoms(KingdomsCardPerKind));
                return cards;
            }
        }

        public static IList<Card> Init(GameType gameType)
        {
            List<Card> board = InitBoardBase();

            IEnumerable<Kind> kingdomKinds;
            switch (gameType)
            {
                case GameType.FirstGame:
                    kingdomKinds = FirstGame;
                    break;
                case GameType.BigMoney:
                   kingdomKinds = BigMoney;
                    break;
                case GameType.Interaction:
                    kingdomKinds = Interaction;
                    break;
                default:
                    throw new NotSupportedException();

            }

            foreach (var kind in kingdomKinds)
            {
                board.AddRange(CardFactory.CreateKingdom(kind, KingdomsCardPerKind));
            }

            return board;

        }




        private static IEnumerable<Kind> FirstGame
        {
            get
            {
                return new Kind[] { 
                    Kind.Workshop,
                    Kind.Woodcutter,
                    Kind.Cellar,
                    Kind.Moat,
                    Kind.Smithy,
                    Kind.Market,
                    Kind.Milicia,
                    Kind.Mine,
                    Kind.Remodel,
                    Kind.Village,
                };
            }
        }

        private static IEnumerable<Kind> BigMoney
        {
            get
            {
                return new Kind[] { 
                    Kind.Adventurer,
                    Kind.Bureaucrat,
                    Kind.Chancellor,
                    Kind.Chapel,
                    Kind.Feast,
                    Kind.Laboratory,
                    Kind.Market,
                    Kind.Mine,
                    Kind.MoneyLender,
                    Kind.Throneroom,
                };
            }
        }


        private static IEnumerable<Kind> Interaction
        {
            get
            {
                return new Kind[] { 
                    Kind.Bureaucrat,
                    Kind.Chancellor,
                    Kind.Councilroom,
                    Kind.Festival,
                    Kind.Library,
                    Kind.Milicia,
                    Kind.Moat,
                    Kind.Spy,
                    Kind.Thief,
                    Kind.Village,
                };
            }
        }




        //Size Distortion: Cellar, Chapel, Feast, Gardens, Laboratory, Thief, Village, Witch, Woodcutter, Workshop 

        //Village Square: Bureaucrat, Cellar, Festival, Library, Market, Remodel, Smithy, Throne Room, Village, Woodcutter 





        private static List<Card> InitBoardBase()
        {
            List<Card> cards = new List<Card>();
            cards.AddRange(CreateCards(CardFactory.CreateCopper, 30));
            cards.AddRange(CreateCards(CardFactory.CreateSilver, 30));
            cards.AddRange(CreateCards(CardFactory.CreateGold, 30));
            cards.AddRange(CreateCards(CardFactory.CreateEstate, 8));
            cards.AddRange(CreateCards(CardFactory.CreateDuchy, 8));
            cards.AddRange(CreateCards(CardFactory.CreateProvince, 8));
            cards.AddRange(CreateCards(CardFactory.CreateMalediction, 20));
            return cards;
        }



        private delegate Card CardCreator();

        private static IEnumerable<Card> CreateCards(CardCreator func, int nb)
        {
            for (int i = 0; i < nb; i++)
                yield return func.Invoke();
        }



        private static IEnumerable<Card> CreateKingdoms(int kingdomsPerPile)
        {
            List<Card> cards = new List<Card>(kingdomsPerPile);
            var kinds = Enum.GetValues(typeof(Kind)).Cast<int>().ToList();
            while (cards.Count < kingdomsPerPile)
            {

            }
            return cards;
        }


        private static IEnumerable<int> RandomIndexes(int nbvalues, int maxvalue)
        {
            Random r = new Random();
            HashSet<int> result = new HashSet<int>();
            while (result.Count < nbvalues)
            {
                int j = r.Next(maxvalue);
                if (!result.Contains(j)) result.Add(j);
            }
            return result;
        }

    }
}
